// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CollectionAssertionExtensions.cs" company="CSLib.Net Team">
//   Copyright (c) Roman "4ux-nbIx" Novitsky 2010
// </copyright>
// <summary>
//   Defines various collection assertion extension methods.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

#define DEBUG

namespace CSLib.Net.Extensions
{
  #region Namespace Imports

  using System;
  using System.Collections.Generic;
  using System.Diagnostics;

  using Annotations;

  using Diagnostics;

  #endregion

  // ReSharper disable ValueAnalysis

  /// <summary>
  /// Defines various collection assertion extension methods.
  /// </summary>
  [DebuggerStepThrough]
  [DebuggerNonUserCode]
  [UsedImplicitly(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.WithMembers)]
  public static class CollectionAssertionExtensions
  {
    #region Public Methods

    /// <summary>
    /// Asserts that a specified <see cref="IEnumerable{T}">collection</see> contains only unique items.
    /// </summary>
    /// <typeparam name="T">
    /// The type of collection items.
    /// </typeparam>
    /// <param name="collection">
    /// A <see cref="IEnumerable{T}">collection</see> to check.
    /// </param>
    /// <param name="messageFormat">
    /// A composite format string.
    /// </param>
    /// <param name="messageArguments">
    /// An array of message arguments to format.
    /// </param>
    [Conditional("DEBUG")]
    [StringFormatMethod("messageFormat")]
    public static void AllElementsAreUnique<T>(
      [NotNull] IEnumerable<T> collection,
      [NotNull] string messageFormat,
      [CanBeNull] params object[] messageArguments)
    {
      CollectionAssert.AllElementsAreUnique(collection, messageFormat, messageArguments);
    }

    /// <summary>
    /// Asserts that a specified <see cref="IEnumerable{T}">collection</see> contains a specified item.
    /// </summary>
    /// <typeparam name="T">
    /// The type of collection items.
    /// </typeparam>
    /// <param name="collection">
    /// A <see cref="IEnumerable{T}">collection</see> to check.
    /// </param>
    /// <param name="item">
    /// An item to check.
    /// </param>
    /// <param name="messageFormat">
    /// A composite format string.
    /// </param>
    /// <param name="messageArguments">
    /// An array of message arguments to format.
    /// </param>
    [Conditional("DEBUG")]
    [StringFormatMethod("messageFormat")]
    public static void AssertContains<T>(
      [NotNull] this IEnumerable<T> collection, 
      [NotNull] T item, 
      [NotNull] string messageFormat, 
      [CanBeNull] params object[] messageArguments)
    {
      CollectionAssert.Contains(collection, item, messageFormat, messageArguments);
    }


    /// <summary>
    /// Asserts that a specified <see cref="IEnumerable{T}">collection</see> contains an item defined by the predicate.
    /// </summary>
    /// <typeparam name="T">The type of collection items.</typeparam>
    /// <param name="collection">A <see cref="IEnumerable{T}">collection</see> to check.</param>
    /// <param name="predicate">The predicate.</param>
    /// <param name="messageFormat">A composite format string.</param>
    /// <param name="messageArguments">An array of message arguments to format.</param>
    [Conditional("DEBUG")]
    [StringFormatMethod("messageFormat")]
    public static void AssertContains<T>(
      [NotNull] this IEnumerable<T> collection,
      [NotNull] Func<T, bool> predicate,
      [NotNull] string messageFormat,
      [CanBeNull] params object[] messageArguments)
    {
      CollectionAssert.Contains(collection, predicate, messageFormat, messageArguments);
    }


    /// <summary>
    /// Asserts that a specified <see cref="IDictionary{TKey, TValue}"/> contains a specified key.
    /// </summary>
    /// <typeparam name="TKey">
    /// The type of the key.
    /// </typeparam>
    /// <typeparam name="TValue">
    /// The type of the value.
    /// </typeparam>
    /// <param name="dictionary">
    /// A <see cref="IDictionary{TKey, TValue}"/> to check.
    /// </param>
    /// <param name="key">
    /// A key to check.
    /// </param>
    /// <param name="messageFormat">
    /// A <see cref="System.String"/> containing composite message format.
    /// </param>
    /// <param name="messageArguments">
    /// An array of message arguments to format.
    /// </param>
    [Conditional("DEBUG")]
    [StringFormatMethod("detailMessageFormat")]
    public static void AssertContainsKey<TKey, TValue>(
      [NotNull] this IDictionary<TKey, TValue> dictionary, 
      [NotNull] TKey key, 
      [NotNull] string messageFormat, 
      [CanBeNull] params object[] messageArguments)
    {
      CollectionAssert.ContainsKey(dictionary, key, messageFormat, messageArguments);
    }


    /// <summary>
    /// Asserts that the specified collection is empty.
    /// </summary>
    /// <typeparam name="T">
    /// Collection items type.
    /// </typeparam>
    /// <param name="collection">
    /// A <see cref="IEnumerable{T}">collection</see> to check.
    /// </param>
    /// <param name="messageFormat">
    /// A <see cref="System.String"/> message to display.
    /// </param>
    /// <param name="messageArguments">
    /// An array of message arguments to format.
    /// </param>
    [Conditional("DEBUG")]
    [StringFormatMethod("messageFormat")]
    public static void AssertIsEmpty<T>(
      [NotNull] this IEnumerable<T> collection, [NotNull] string messageFormat, [CanBeNull] params object[] messageArguments)
    {
      CollectionAssert.IsEmpty(collection, messageFormat, messageArguments);
    }


    /// <summary>
    /// Asserts that the specified collection is not empty.
    /// </summary>
    /// <typeparam name="T">
    /// Collection items type.
    /// </typeparam>
    /// <param name="collection">
    /// A <see cref="IEnumerable{T}">collection</see> to check.
    /// </param>
    /// <param name="messageFormat">
    /// A <see cref="System.String"/> message to display.
    /// </param>
    /// <param name="messageArguments">
    /// An array of message arguments to format.
    /// </param>
    [Conditional("DEBUG")]
    [StringFormatMethod("messageFormat")]
    public static void AssertIsNotEmpty<T>(
      [NotNull] this IEnumerable<T> collection, [NotNull] string messageFormat, [CanBeNull] params object[] messageArguments)
    {
      CollectionAssert.IsNotEmpty(collection, messageFormat, messageArguments);
    }


    /// <summary>
    /// Asserts that a specified <see cref="IEnumerable{T}">collection</see> doesn't contain a specified item.
    /// </summary>
    /// <typeparam name="T">
    /// The type of collection items.
    /// </typeparam>
    /// <param name="collection">
    /// A <see cref="IEnumerable{T}">collection</see> to check.
    /// </param>
    /// <param name="item">
    /// An item to check.
    /// </param>
    /// <param name="messageFormat">
    /// A composite format string.
    /// </param>
    /// <param name="messageArguments">
    /// An array of message arguments to format.
    /// </param>
    [Conditional("DEBUG")]
    [StringFormatMethod("messageFormat")]
    public static void AssertNotContains<T>(
      [NotNull] this IEnumerable<T> collection, 
      [NotNull] T item, 
      [NotNull] string messageFormat, 
      [CanBeNull] params object[] messageArguments)
    {
      CollectionAssert.NotContains(collection, item, messageFormat, messageArguments);
    }


    /// <summary>
    /// Asserts that a specified <see cref="IEnumerable{T}">collection</see> doesn't contain an item defined by the predicate.
    /// </summary>
    /// <typeparam name="T">The type of collection items.</typeparam>
    /// <param name="collection">A <see cref="IEnumerable{T}">collection</see> to check.</param>
    /// <param name="predicate">The predicate.</param>
    /// <param name="messageFormat">A composite format string.</param>
    /// <param name="messageArguments">An array of message arguments to format.</param>
    [Conditional("DEBUG")]
    [StringFormatMethod("messageFormat")]
    public static void AssertNotContains<T>(
      [NotNull] this IEnumerable<T> collection,
      [NotNull] Func<T, bool> predicate,
      [NotNull] string messageFormat,
      [CanBeNull] params object[] messageArguments)
    {
      CollectionAssert.NotContains(collection, predicate, messageFormat, messageArguments);
    }


    /// <summary>
    /// Asserts that a specified <see cref="IDictionary{TKey, TValue}"/> doesn't contain a specified key-value pair.
    /// </summary>
    /// <typeparam name="TKey">
    /// The type of the key.
    /// </typeparam>
    /// <typeparam name="TValue">
    /// The type of the value.
    /// </typeparam>
    /// <param name="dictionary">
    /// A <see cref="IDictionary{TKey, TValue}"/> to check.
    /// </param>
    /// <param name="key">
    /// A key to check.
    /// </param>
    /// <param name="value">
    /// A value to check.
    /// </param>
    /// <param name="messageFormat">
    /// A <see cref="System.String"/> containing composite message format.
    /// </param>
    /// <param name="messageArguments">
    /// An array of message arguments to format.
    /// </param>
    [Conditional("DEBUG")]
    [StringFormatMethod("detailMessageFormat")]
    public static void AssertNotContains<TKey, TValue>(
      [NotNull] this IDictionary<TKey, TValue> dictionary, 
      [NotNull] TKey key, 
      [NotNull] TValue value, 
      [NotNull] string messageFormat, 
      [CanBeNull] params object[] messageArguments)
    {
      CollectionAssert.NotContains(dictionary, key, value, messageFormat, messageArguments);
    }


    /// <summary>
    /// Asserts that a specified <see cref="IDictionary{TKey, TValue}"/> doesn't contain a specified key.
    /// </summary>
    /// <typeparam name="TKey">
    /// The type of the key.
    /// </typeparam>
    /// <typeparam name="TValue">
    /// The type of the value.
    /// </typeparam>
    /// <param name="dictionary">
    /// A <see cref="IDictionary{TKey, TValue}"/> to check.
    /// </param>
    /// <param name="key">
    /// A key to check.
    /// </param>
    /// <param name="messageFormat">
    /// A <see cref="System.String"/> containing composite message format.
    /// </param>
    /// <param name="messageArguments">
    /// An array of message arguments to format.
    /// </param>
    [Conditional("DEBUG")]
    [StringFormatMethod("detailMessageFormat")]
    public static void AssertNotContainsKey<TKey, TValue>(
      [NotNull] this IDictionary<TKey, TValue> dictionary, 
      [NotNull] TKey key, 
      [NotNull] string messageFormat, 
      [CanBeNull] params object[] messageArguments)
    {
      CollectionAssert.NotContainsKey(dictionary, key, messageFormat, messageArguments);
    }

    #endregion
  }
}